package de.mrapp.materialview.library;

import de.mrapp.materialview.library.drawable.CircularProgressDrawable;
import de.mrapp.materialview.library.utils.AttrUtils;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.element.Element;
import ohos.agp.render.Canvas;
import ohos.app.Context;

public class CircularProgressBar extends Component implements Element.OnChangeListener, Component.DrawTask, Component.BindStateChangedListener, Component.EstimateSizeListener, Component.LayoutRefreshedListener {

    /**
     * The color of the circular progress bar.
     */
    private int color;

    /**
     * The thickness of the circular progress bar.
     */
    private int thickness;

    /**
     * The drawable, which is shown by the view.
     */
    private CircularProgressDrawable circularProgressDrawable;

    public CircularProgressBar(Context context) {
        this(context, null);
    }

    public CircularProgressBar(Context context, AttrSet attrSet) {
        this(context, attrSet, "");
    }

    public CircularProgressBar(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        addDrawTask(this);
        setEstimateSizeListener(this);
        setBindStateChangedListener(this);
        initialize(attrSet);
    }

    private void initialize(AttrSet attrSet) {
        color = AttrUtils.getColorFromAttr(attrSet, "pb_color", ResourceTable.Color_colorAccent);
        thickness = AttrUtils.getDimensionFromAttr(attrSet, "pb_thickness", 5);
        initializeDrawable();
    }

    private void initializeDrawable() {
        circularProgressDrawable = new CircularProgressDrawable(color, thickness);
        circularProgressDrawable.setCallback(this);
    }

    /**
     * Returns the color of the circular progress bar.
     *
     * @return The color of the circular progress bar as an {@link Integer} value
     */
    public final int getColor() {
        return color;
    }

    /**
     * Sets the color of the circular progress bar.
     *
     * @param color The color, which should be set, as an {@link Integer} value
     */
    public final void setColor(final int color) {
        this.color = color;
        initializeDrawable();
        invalidate();
    }

    /**
     * Returns the thickness of the circular progress bar.
     *
     * @return The thickness of the circular progress bar in pixels as an {@link Integer} value
     */
    public final int getThickness() {
        return thickness;
    }

    /**
     * Sets the thickness of the circular progress bar.
     *
     * @param thickness The thickness, which should be set, in pixels as an {@link Integer} value
     */
    public final void setThickness(final int thickness) {
        this.thickness = thickness;
        initializeDrawable();
        invalidate();
    }

    @Override
    public void onChange(Element element) {
        setBackground(element);
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        circularProgressDrawable.drawToCanvas(canvas);

    }

    @Override
    public void onComponentBoundToWindow(Component component) {
        if (circularProgressDrawable != null) {
            circularProgressDrawable.start();
        }
    }

    @Override
    public void onComponentUnboundFromWindow(Component component) {

    }

    @Override
    public boolean onEstimateSize(int widthEstimateConfig, int heightEstimateConfig) {
        final int width = EstimateSpec.getSize(widthEstimateConfig) + getPaddingLeft() + getPaddingRight();
        final int height = EstimateSpec.getSize(heightEstimateConfig) + getPaddingTop() + getPaddingBottom();
        setEstimatedSize(width, height);
        return false;
    }

    @Override
    public void onRefreshed(Component component) {
        int width = component.getWidth();
        int height = component.getHeight();
        circularProgressDrawable.setBounds(getPaddingLeft(), getPaddingTop(), width - getPaddingRight(), height - getPaddingBottom());
    }
}
